# -*- coding: utf-8 -*-

"""
@author: Laowang
@contact: QQ:1125564921
@Created on: 2022/6/20
@Remark: 
"""


from collections import defaultdict
from typing import Any
from typing import TypeVar

_KT = TypeVar("_KT")
_VT = TypeVar("_VT")

class SubscribeMeta:
    """ """

    def __init__(self) -> None:
        """ """
        self._handles: set = set()

    def add(self, handle: Any):
        """ """
        self._handles.add(handle)

    def remove(self, handle: Any):
        """ """
        self._handles.remove(handle)

    def send_all(self, msg: Any):
        """ """
        for handle in self._handles:
            handle(msg)
    
    def handles(self):
        """ """
        return self._handles

    def __len__(self) -> int:
        """ """
        return len(self._handles)

    def __repr__(self) -> str:
        """ """
        return repr(self._handles)

    def __iter__(self):
        """ """
        return (h for h in self._handles)

    handles = property(handles)


_exchange = defaultdict(SubscribeMeta)


class Exchange:
    """ """

    def __init__(self) -> None:
        """ """
        self._exchange: defaultdict(SubscribeMeta) = _exchange

    def on_bind(self, name: Any, handle: Any):
        """ """
        self._exchange[name].add(handle)

    def out_bind(self, name: Any, handle: Any = None):
        """ """
        if handle is None:
            self._exchange.pop(name, "")
            return

        handles: set = self._exchange[name]
        if len(handles) > 0:
            handles.remove(handle)
        else:
            self._exchange.pop(name, "")

    def handles(self, name: Any = None):
        """ """
        if name is None:
            return self._exchange
        else:
            return self._exchange[name]

    def __getitem__(self, __k: _KT):
        """ """
        return self._exchange[__k]

    def __setitem__(self, __k: _KT, __v: _VT):
        """ """
        self.on_bind(__k, __v)
